package com.backend.util;

import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@Component
public class JwtUtils {
    @Value("${backend.jwt.key}")
    private String key;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 将JWT令牌加入黑名单
     */
    public boolean invalidateJwt(String headerToken) {
        // 验证请求头中的令牌格式
        if (headerToken == null || !headerToken.startsWith("Bearer ")) {
            return false;
        }
        String token = headerToken.substring(7);
        try {
            // 解析令牌并获取声明信息
            Claims claims =JWTUtil.parseJWT(key, token);
            // 获取令牌ID和过期时间
            String jti = claims.getId();
            Date expiration = claims.getExpiration();
            // 将令牌加入Redis黑名单
            return deleteToken(jti, expiration);
        } catch (Exception e) {
            // 令牌验证失败
            return false;
        }
    }

    /**
     * 将令牌存入Redis黑名单，设置与令牌剩余有效期相同的过期时间
     */
    private boolean deleteToken(String jti, Date expiration) {
        try {
            // 计算令牌剩余有效期（秒）
            long expireSeconds = (expiration.getTime() - System.currentTimeMillis()) / 1000;

            if (expireSeconds > 0) {
                // 将令牌ID存入Redis，并设置过期时间
                redisTemplate.opsForValue()
                        .set(Const.JWT_BLACK_LIST + jti, "invalid", expireSeconds, TimeUnit.SECONDS);
                return true;
            }
            return false;
        } catch (Exception e) {
            // 处理Redis操作异常
            return false;
        }
    }

    /**
     * 检查令牌是否在黑名单中
     */
    public boolean isTokenBlacklisted(String jti) {
        return redisTemplate.hasKey(Const.JWT_BLACK_LIST + jti);
    }
}
